home *** CD-ROM | disk | FTP | other *** search
/ Java Programmer's Toolkit / Java Programmer's Toolkit.iso / gs3.53 / gslp.ps < prev    next >
Text File  |  1996-01-10  |  15KB  |  518 lines

  1. (
  2. true setglobal
  3. (traceop.ps) run
  4. /def 2 0 traceop
  5. false setglobal
  6. )pop
  7. %    Copyright (C) 1991, 1995 Aladdin Enterprises.  All rights reserved.
  8. % This file is part of Aladdin Ghostscript.
  9. % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  10. % or distributor accepts any responsibility for the consequences of using it,
  11. % or for whether it serves any particular purpose or works at all, unless he
  12. % or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  13. % License (the "License") for full details.
  14. % Every copy of Aladdin Ghostscript must include a copy of the License,
  15. % normally in a plain ASCII text file named PUBLIC.  The License grants you
  16. % the right to copy, modify and redistribute Aladdin Ghostscript, but only
  17. % under certain conditions described in the License.  Among other things, the
  18. % License requires that the copyright notice and this notice be preserved on
  19. % all copies.
  20.  
  21. % gslp.ps - format and print text
  22.  
  23. % This utility provides functionality approximately equivalent to the Unix
  24. % `enscript' program.  It prints plain text files using a single font.
  25. % It currently handles tabs and formfeeds, but not backspaces.
  26. % It only works with fixed-pitch fonts.
  27. % Standard flags implemented:
  28. %    -12BclqRr -b -f -F -L -p
  29. % Sun flags implemented:
  30. %    -T<n>    set tab width
  31. % Flags ignored:
  32. %    -GghKkmow -# -C -d -J -n -P -S -s -t -v
  33. % Flags added:
  34. %    --detect
  35. %        treats the file as PostScript if it starts with %!
  36. %    --(heading|footing)-(left|center|right) <string>
  37. %        sets the heading/footing fields; use -B first to clear
  38. %    --first-page <n>
  39. %        sets the first page to print
  40. %    --last-page <n>
  41. %        sets the last page to print
  42. %    --spacing <n>
  43. %        for double (n=2), triple (n=3), etc. spacing
  44. % Also, the string %# in a heading or footing is replaced with the page #.
  45. /PageNumberString (%#) def
  46.  
  47. /lpdict 150 dict def
  48. lpdict begin
  49.  
  50. % build iso-latin-1 version of a font
  51. /font-to-iso-latin-1 {    % <font> font-to-iso-latin-1 <font>
  52.     %% reencode for iso latin1; from the 2nd edition red book, sec 5.6.1
  53.     dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall
  54.     /Encoding ISOLatin1Encoding def currentdict end
  55.     dup /FontName get 80 string cvs (-ISOLatin1) concatstrings cvn 
  56.     exch definefont
  57. } def
  58.  
  59. /find-latin-font {    % <name> find-latin-font <font>
  60.   findfont font-to-iso-latin-1
  61. } def
  62.  
  63. % Define the initial values of the printing parameters.
  64.  
  65. /BodyFont null def        % use default
  66.   /defaultBodyFont
  67.     { /Courier find-latin-font Landscape { 7 } { 10 } ifelse scalefont } def
  68. /Columns 1 def
  69. /DetectFileType false def
  70. /Footers false def
  71. /FootingLeft () def
  72. /FootingCenter () def
  73. /FootingRight () def
  74. /Headers true def
  75. /HeadingLeft () def
  76. /HeadingCenter () def
  77. /HeadingRight (page ) PageNumberString concatstrings def
  78. /HeadingFont null def        % use default
  79.   /defaultHeadingFont
  80.     { /Courier-Bold find-latin-font 10 scalefont } def
  81. /Landscape false def
  82. /MarginBottom 36 def        % 1/2"
  83. /MarginLeft 36 def        % 1/2"
  84. /MarginRight 36 def        % 1/2"
  85. /MarginTop 36 def        % 1/2"
  86. /MaxLines 9999 def        % max lines per page
  87. /Noisy true def            % i.e., not quiet
  88. /OutFile null def        % null = write directly to device
  89. /PageFirst 1 def
  90. /PageLast 99999 def
  91. /Spacing 1 def
  92. /Tab 8 def
  93. /Truncate false def        % wrap long lines, don't truncate
  94.  
  95. % When writing to a file, we want to write out PostScript;
  96. % when writing to the printer, we want to execute it;
  97. % some commands should be executed regardless.
  98. % lpexec provides for all this.
  99.  
  100. /lpexec        % <arg1> ... <argn> </op> <n> <do_always> lpexec -
  101.  { OutFile null eq
  102.     { pop 1 add true
  103.     }
  104.     { /t exch def 1 add /n exch def cvx
  105.       n { n -1 roll dup wosp } repeat
  106.       OutFile (\n) writestring
  107.       n t
  108.     }
  109.    ifelse
  110.     { pop load exec }
  111.     { { pop } repeat }
  112.    ifelse
  113.  } def
  114.  
  115. /lpmoveto
  116.  { /moveto 2 true lpexec
  117.  } def
  118. /lpshow
  119.  { dup length 0 ne { /show 1 false lpexec } { pop } ifelse
  120.  } def
  121. /lpsetmyfont
  122.  { dup load setfont
  123.    OutFile null ne { cvx /setfont 1 false lpexec } { pop } ifelse
  124.  } def
  125.  
  126. % Define some utility procedures.
  127.  
  128. /banner        % ypos left center right
  129.  { /HFont lpsetmyfont
  130.    3 -1 roll bannerstring pop 0 4 index pwidth showline2 pop
  131.    exch bannerstring pwidth exch sub 2 div 3 index pwidth showline2 pop
  132.    bannerstring pwidth exch sub
  133.    3 -1 roll pwidth showline2 pop
  134.  } def
  135.  
  136. /bannerstring    % string -> string width
  137.   { PageNumberString search
  138.      { exch pop pindex 4 string cvs concatstrings exch concatstrings
  139.      }
  140.     if dup stringwidth pop
  141.   } def
  142.  
  143. /beginpage
  144.  { /lindex 0 def
  145.    /skipping pindex PageFirst ge pindex PageLast le and not def
  146.    /save 0 true lpexec /pagesave exch def
  147.    skipping { nulldevice   /OutFile null def } if
  148.    Headers
  149.     { lheight hdescent add
  150.       HeadingLeft HeadingCenter HeadingRight banner
  151.     } if
  152.    /BFont lpsetmyfont
  153.  } def
  154.  
  155. /endpage
  156.  { lindex 0 ne
  157.     { Footers
  158.        { topskip plength sub hdescent add
  159.          FootingLeft FootingCenter FootingRight banner
  160.        } if
  161.       /showpage 0 false lpexec
  162.     } if
  163.    pagesave /restore 0 true lpexec
  164.    /pindex pindex 1 add def
  165.  } def
  166.  
  167. /fontheight    % <font> fontheight <ascent> <height>
  168.  { gsave setfont
  169.    newpath 0 0 moveto
  170.    (|^_j) false charpath
  171.    pathbbox exch pop dup 2 index sub 4 -2 roll pop pop
  172.    grestore exch 1.25 mul exch 1.25 mul
  173.  } def
  174.  
  175. /wosp
  176.  { OutFile ( ) writestring OutFile exch write==only
  177.  } def
  178.  
  179. /outfont        % name font ->
  180.  { OutFile null ne
  181.     { exch wosp
  182.       dup /FontName get 
  183.       dup wosp OutFile ( findfont) writestring
  184.       %% reencode for iso latin1; from the 2nd edition red book, sec 5.6.1
  185.       OutFile ( 
  186.     dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall
  187.     /Encoding ISOLatin1Encoding def currentdict end
  188.       ) writestring
  189.       wosp OutFile (-ISOLatin1 exch definefont) writestring
  190.       /FontMatrix get 0 get 1000 mul round cvi wosp
  191.       OutFile ( scalefont def\n) writestring
  192.     }
  193.     { pop pop
  194.     }
  195.    ifelse
  196.  } def
  197.  
  198. /StringFF (\f) def
  199. /CharFF StringFF 0 get def
  200. /StringTAB (\t) def
  201. /CharTAB StringTAB 0 get def
  202.  
  203. /showline        % line -> leftover_line (handles \f)
  204.  {  { showline1 dup length 0 eq { exit } if
  205.       dup 0 get CharFF ne { exit } if
  206.       endpage beginpage
  207.       skip1
  208.     }
  209.    loop
  210.  } def
  211.  
  212. /showline1        % line -> leftover_line (handles page break)
  213.  { lindex llength eq { endpage beginpage } if
  214.    lindex colines idiv cowidth mul        % x
  215.    lindex colines mod 1 add lheight mul neg fascent sub    % y
  216.    1 index cowidth add
  217.    showline2
  218.    /lindex lindex 1 add def
  219.  } def
  220.  
  221. /showline2    % string x y xlimit -> leftover_string (handles tabs)
  222.  { 2 index exch 5 2 roll lpmoveto    % xinit xlimit string
  223.     { showline3 dup length 0 eq { exit } if
  224.       dup 0 get CharTAB ne { exit } if
  225.       currentpoint exch 4 index sub tabwx div
  226.     0.05 add ceiling tabwx mul 4 index add exch lpmoveto
  227.       skip1
  228.       currentpoint pop 2 index ge { exit } if
  229.     }
  230.    loop exch pop exch pop
  231.  } def
  232.  
  233. /showline3    % xlimit string -> xlimit leftover_string
  234.         % (finds line break / tab / formfeed)
  235.  { currentpoint pop 2 index exch sub
  236.      cwx div 0.1 add cvi 0 max 1 index length min
  237.    1 index 0 3 -1 roll getinterval
  238.     % look for \f or \t
  239.    StringFF search { exch pop exch pop } if
  240.    StringTAB search { exch pop exch pop } if
  241.    dup lpshow
  242.    length dup 2 index length exch sub getinterval
  243.  } def
  244.  
  245. /skip1
  246.  { dup length 1 sub 1 exch getinterval
  247.  } def
  248.  
  249. /e== {        % <object> e== - -- print an object to stderr
  250.   (%stderr) (w) file dup 3 -1 roll write==only flushfile
  251. } def
  252.  
  253. /eprint {    % <string> eprint - -- print a string to stderr
  254.   (%stderr) (w) file dup 3 -1 roll writestring flushfile
  255. } def
  256.  
  257. % The main printing procedure
  258.  
  259. /lp        % file initial_chars ->
  260.  { /lpline exch def
  261.    /lpfile exch def
  262.    /save 0 true lpexec
  263.  
  264. % Initialize the device and fonts.
  265.    /BFont
  266.      BodyFont null eq { defaultBodyFont } { BodyFont } ifelse def
  267.    /BFont BFont outfont
  268.    Headers Footers or
  269.     { /HFont
  270.     HeadingFont null eq { defaultHeadingFont } { HeadingFont } ifelse def
  271.       /HFont HFont outfont
  272.     }
  273.    if
  274.  
  275. % Get the layout parameters.
  276.    clippath
  277.    Landscape { 90 /rotate 1 true lpexec } if
  278.    BFont setfont ( ) stringwidth pop /cwx exch def
  279.      cwx Tab mul /tabwx exch def
  280.    BFont fontheight /fheight exch def /fascent exch def
  281.    Headers Footers or { HFont fontheight } { 0 0 } ifelse
  282.      /hheight exch def /hascent exch def
  283.      /hdescent hheight hascent sub def
  284.    fheight Spacing mul /lheight exch def
  285.    Headers { hheight lheight add } { 0 } ifelse
  286.      /topskip exch def
  287.    Footers { hheight lheight add } { 0 } ifelse
  288.      /botskip exch def
  289.    /pskip topskip botskip add def
  290.     % Translate the page so that (0,0) corresponds to
  291.     % the top of the topmost body line.
  292.    pathbbox
  293.      2 index sub MarginBottom MarginTop add sub /plength exch def
  294.      2 index sub MarginLeft MarginRight add sub /pwidth exch def
  295.      pwidth Columns div /cowidth exch def
  296.      exch MarginLeft add
  297.      exch MarginBottom add plength add topskip sub
  298.      /translate 2 true lpexec
  299.    plength pskip sub lheight div cvi MaxLines min
  300.      dup /colines exch def
  301.      Columns mul /llength exch def
  302.    OutFile null ne { nulldevice } if
  303.  
  304. % Print layout
  305.    Noisy
  306.     { (Page height = ) eprint llength e==
  307.       (.\n) eprint flush
  308.     } if
  309.  
  310. % Disable stack recording so we can use stopped with readline.
  311.    $error /recordstacks false put
  312.  
  313. % Initialize for the first page.
  314.    /lbuf 1000 string def
  315.    /pindex 1 def
  316.    beginpage
  317.  
  318. % Iterate through the file.
  319.    lpline
  320.     { dup length /pos exch def
  321.       lbuf exch 0 exch putinterval
  322.        { lpfile lbuf pos lbuf length pos sub getinterval readline } stopped
  323.        {    % Filled the line before a CR or EOF.
  324.          exch pop showline
  325.        }
  326.        {    % Reached CR and/or EOF first.
  327.          exch length pos add lbuf exch 0 exch getinterval
  328.      1 index { showline } if        % omit final empty line
  329.       { dup length 0 eq Truncate or { pop () exit } if
  330.         showline
  331.       }
  332.      loop
  333.      exch not { exit } if
  334.        }
  335.       ifelse
  336.     } loop
  337.    pop
  338.  
  339. % Wrap up.
  340.    endpage
  341.    /restore 0 true lpexec
  342.  
  343.  } def
  344.  
  345. end
  346.  
  347. % Usage: <file> lp
  348. %   prints <file> using the current parameter settings.
  349. % Usage: [ <arg1> ... <argn> ] lpcommand
  350. %   interprets args like a command line.
  351.  
  352. /lp { save   lpdict begin () lp end   restore } def
  353.  
  354. lpdict begin
  355.  
  356. /splitfn        % (FontNNN) -> <font>
  357.  { dup /arg exch def length
  358.     { dup 0 le { exit } if
  359.       dup 1 sub arg exch get dup 48 ge exch 59 le and not { exit } if
  360.       1 sub
  361.     } loop
  362.    arg exch 0 exch getinterval dup cvn find-latin-font
  363.    exch arg exch anchorsearch pop pop cvr scalefont
  364.  } def
  365.  
  366. % Parse the command line switches.
  367.  
  368. /doswitch    % argn ... arg1 (-?) restofswitch ->
  369.  { exch dup cvn lpdict exch known
  370.     { cvn load exec }
  371.     { exch pop (Unknown switch: ) eprint eprint (\n) eprint }
  372.    ifelse
  373.  } def
  374.  
  375. /more        % argn ... arg1 restofswitch ->
  376.  { dup length 0 ne
  377.     { (- ) dup 1 3 index 0 get put
  378.       exch dup length 1 sub 1 exch getinterval
  379.       doswitch
  380.     }
  381.     { pop
  382.     }
  383.    ifelse
  384.  } def
  385.  
  386. /-- { (--) exch concatstrings
  387.       dup cvn lpdict exch known
  388.        { cvn load exec }
  389.        { (Unknown switch: ) eprint eprint (\n) eprint }
  390.       ifelse
  391.     } def
  392. /--columns { cvi 1 max /Columns exch def } def
  393. /--detect { /DetectFileType true def } def
  394. /--first-page { cvi /PageFirst exch def } def
  395. /--footing-center { /FootingCenter exch def   /Footers true def } def
  396. /--footing-left { /FootingLeft exch def   /Footers true def } def
  397. /--footing-right { /FootingRight exch def   /Footers true def} def
  398. /--heading-center { /HeadingCenter exch def   /Headers true def } def
  399. /--heading-left { /HeadingLeft exch def   /Headers true def } def
  400. /--heading-right { /HeadingRight exch def   /Headers true def } def
  401. /--margin-bottom { cvr 72.0 mul /MarginBottom exch def } def
  402. /--margin-left { cvr 72.0 mul /MarginLeft exch def } def
  403. /--margin-right { cvr 72.0 mul /MarginRight exch def } def
  404. /--margin-top { cvr 72.0 mul /MarginTop exch def } def
  405. /--last-page { cvi /PageLast exch def } def
  406. /--spacing { cvr /Spacing exch def } def
  407.  
  408. /-# { pop } def        % ignore
  409. /-+ { -- } def
  410. (-1)cvn { /Columns 1 def   more } def
  411. (-2)cvn { /Columns 2 def   more } def
  412. /-b { /HeadingLeft exch def   /HeadingCenter () def   /HeadingRight PageNumberString def
  413.       /Headers true def
  414.       /break true def
  415.     } def
  416. /-B { /HeadingLeft () def   /HeadingCenter () def   /HeadingRight () def
  417.       /Headers false def
  418.       /FootingLeft () def   /FootingCenter () def   /FootingRight () def
  419.       /Footers false def
  420.       /break true def
  421.       more
  422.     } def
  423. /-C { pop } def        % ignore
  424. /-c { /Truncate true def   more } def
  425. /-d { pop } def        % ignore
  426. /-f { splitfn /BodyFont exch def } def
  427. /-F { splitfn /HeadingFont exch def } def
  428. /-G { more } def    % ignore
  429. /-g { more } def    % ignore
  430. /-h { more } def    % ignore
  431. /-J { pop } def        % ignore
  432. /-K { more } def    % ignore
  433. /-k { more } def    % ignore
  434. /-l { 66 -L -B } def
  435. /-L { cvi /MaxLines exch def } def
  436. /-m { more } def    % ignore
  437. /-n { pop } def        % ignore
  438. /-o { more } def    % ignore
  439. /-p { (w) file /OutFile exch def   OutFile (%!\n) writestring } def
  440. /-P { pop } def        % ignore
  441. /-q { /Noisy false def   more } def
  442. /-r { /Landscape true def   more } def
  443. /-R { /Landscape false def   more } def
  444. /-S { pop } def        % ignore
  445. /-s { pop } def        % ignore
  446. /-T { cvi /Tab exch def } def
  447. /-v { pop } def        % ignore
  448. /-w { more } def    % ignore
  449.  
  450. /lp1        % filename ->
  451.  { break not { dup /HeadingLeft exch def } if
  452.    Noisy
  453.     { (Printing ) eprint dup eprint (\n) eprint 
  454.     } if
  455.    (r) file
  456.         % If requested, check for a PostScript file.
  457.    DetectFileType
  458.     { dup 2 string readstring pop dup (%!) eq
  459.        {    % Yes, it's a PostScript file.
  460.          pop dup 80 string readline pop pop cvx exec
  461.        }
  462.        { lp
  463.        }
  464.       ifelse
  465.     }
  466.     { () lp
  467.     }
  468.    ifelse
  469.  } bind def
  470.  
  471. /lpcstring 100 string def
  472.  
  473. end
  474.  
  475. /lpcommand        % [arg1 ... argn] -> -
  476.  {    % Push the commands on the stack in reverse order
  477.    mark exch
  478.    dup length 1 sub -1 0 { 1 index exch get exch } for pop
  479.    lpdict begin
  480.    /break false def
  481.     { dup mark eq { pop exit } if
  482.       dup length 2 ge { dup 0 get (-) 0 get eq } { false } ifelse
  483.        { dup 0 2 getinterval
  484.          exch dup length 2 sub 2 exch getinterval
  485.      doswitch
  486.        }
  487.        { dup  /matched false def
  488.           { /matched true def    lp1 } lpcstring filenameforall
  489.      matched { pop } { lp1 } ifelse        % let the error happen
  490.        }
  491.       ifelse
  492.     } loop
  493.    OutFile null ne
  494.     { OutFile (%stdout) (w) file ne { OutFile closefile } if
  495.       /OutFile null def
  496.     } if
  497.    end
  498.  } def
  499.  
  500. [ shellarguments
  501.  { ] dup length 0 ne
  502.     { lpcommand
  503.     }
  504.     { (Usage: gslp [-12BclqRr] [-b<header] [-f<font>] [-F<hfont>]\n) eprint
  505.       (        [-L<lines>] [-p<outfile>] [-T<tabwidth>] [--columns <n>]\n) eprint
  506.       (        [--detect] [--first-page <page#>] [--last-page <page#>]\n) eprint
  507.       (        [--(heading|footing)-(left|right|center) <string>]\n) eprint
  508.       (        [--margin-(top|bottom|left|right) <inches>]\n) eprint
  509.       (        [--spacing <n>] file1 ... filen\n) eprint
  510.     }
  511.    ifelse
  512.  }
  513.  { pop }
  514. ifelse
  515.